bitkeeper revision 1.1041.2.1 (40e2dccbwLPMSsarwzAscW72tSfuEg)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 30 Jun 2004 15:31:23 +0000 (15:31 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 30 Jun 2004 15:31:23 +0000 (15:31 +0000)
Add resource tracking for pfn mappings in libxc.

tools/libxc/xc_linux_build.c
tools/libxc/xc_linux_restore.c
tools/libxc/xc_netbsd_build.c
tools/libxc/xc_private.c
tools/libxc/xc_private.h

index ceace01b00167bbd95ad0cb4c29f249df96b96fe..c2228b5e9ea26fa19b7007d64b8f30acdb63f66c 100644 (file)
@@ -18,7 +18,7 @@ static int readelfimage_base_and_size(char *elfbase,
                                       unsigned long *pkernstart,
                                       unsigned long *pkernend,
                                       unsigned long *pkernentry);
-static int loadelfimage(char *elfbase, int pmh, unsigned long *parray,
+static int loadelfimage(char *elfbase, void *pmh, unsigned long *parray,
                         unsigned long vstart);
 
 static long get_tot_pages(int xc_handle, u32 domid)
@@ -53,7 +53,7 @@ static int get_pfn_list(int xc_handle,
     return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
 }
 
-static int copy_to_domain_page(int pm_handle,
+static int copy_to_domain_page(void *pm_handle,
                                unsigned long dst_pfn, 
                                void *src_page)
 {
@@ -86,7 +86,8 @@ static int setup_guestos(int xc_handle,
     extended_start_info_t *start_info;
     shared_info_t *shared_info;
     mmu_t *mmu = NULL;
-    int pm_handle=-1, rc;
+    void  *pm_handle=NULL;
+    int rc;
 
     unsigned long nr_pt_pages;
     unsigned long ppt_alloc;
@@ -165,7 +166,7 @@ static int setup_guestos(int xc_handle,
            v_start, v_end);
     printf(" ENTRY ADDRESS: %08lx\n", vkern_entry);
 
-    if ( (pm_handle = init_pfn_mapper((domid_t)dom)) < 0 )
+    if ( (pm_handle = init_pfn_mapper((domid_t)dom)) == NULL )
         goto error_out;
 
     if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
@@ -307,7 +308,7 @@ static int setup_guestos(int xc_handle,
  error_out:
     if ( mmu != NULL )
         free(mmu);
-    if ( pm_handle >= 0 )
+    if ( pm_handle != NULL )
         (void)close_pfn_mapper(pm_handle);
     if ( page_array != NULL )
         free(page_array);
@@ -629,7 +630,7 @@ static int readelfimage_base_and_size(char *elfbase,
     return 0;
 }
 
-static int loadelfimage(char *elfbase, int pmh, unsigned long *parray,
+static int loadelfimage(char *elfbase, void *pmh, unsigned long *parray,
                         unsigned long vstart)
 {
     Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
@@ -649,11 +650,11 @@ static int loadelfimage(char *elfbase, int pmh, unsigned long *parray,
         {
             pa = (phdr->p_vaddr + done) - vstart;
             va = map_pfn_writeable(pmh, parray[pa>>PAGE_SHIFT]);
-            va += pa & (PAGE_SIZE-1);
             chunksz = phdr->p_filesz - done;
             if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
                 chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
-            memcpy(va, elfbase + phdr->p_offset + done, chunksz);
+            memcpy(va + (pa & (PAGE_SIZE-1)),
+                   elfbase + phdr->p_offset + done, chunksz);
             unmap_pfn(pmh, va);
         }
 
@@ -661,11 +662,10 @@ static int loadelfimage(char *elfbase, int pmh, unsigned long *parray,
         {
             pa = (phdr->p_vaddr + done) - vstart;
             va = map_pfn_writeable(pmh, parray[pa>>PAGE_SHIFT]);
-            va += pa & (PAGE_SIZE-1);
             chunksz = phdr->p_memsz - done;
             if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
                 chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
-            memset(va, 0, chunksz);
+            memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
             unmap_pfn(pmh, va);            
         }
     }
index badba75162e5d808ab56b69e291bb436bf439c76..f091914dba099081a6b5c99f5e48afa644de4d4a 100644 (file)
@@ -19,7 +19,6 @@
 #define DPRINTF(_f, _a...) ((void)0)
 #endif
 
-
 static int get_pfn_list(int xc_handle,
                         u32 domain_id, 
                         unsigned long *pfn_buf, 
@@ -53,23 +52,28 @@ static int get_pfn_list(int xc_handle,
  * @param ioctxt i/o context
  * @return 0 on success, non-zero on error.
  */
-static int read_vmconfig(XcIOContext *ioctxt){
+static int read_vmconfig(XcIOContext *ioctxt)
+{
     int err = -1;
-    if(xcio_read(ioctxt, &ioctxt->vmconfig_n, sizeof(ioctxt->vmconfig_n))){
+
+    if ( xcio_read(ioctxt, &ioctxt->vmconfig_n, sizeof(ioctxt->vmconfig_n)) )
         goto exit;
-    }
+
     ioctxt->vmconfig = malloc(ioctxt->vmconfig_n + 1);
-    if(!ioctxt->vmconfig) goto exit;
-    if(xcio_read(ioctxt, ioctxt->vmconfig, ioctxt->vmconfig_n)){
+    if ( ioctxt->vmconfig == NULL ) 
         goto exit;
-    }
+
+    if ( xcio_read(ioctxt, ioctxt->vmconfig, ioctxt->vmconfig_n) )
+        goto exit;
+
     ioctxt->vmconfig[ioctxt->vmconfig_n] = '\0';
     err = 0;
+
   exit:
-    if(err){
-        if(ioctxt->vmconfig){
+    if ( err )
+    {
+        if ( ioctxt->vmconfig != NULL )
             free(ioctxt->vmconfig);
-        }
         ioctxt->vmconfig = NULL;
         ioctxt->vmconfig_n = 0;
     }
@@ -126,12 +130,13 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
 
     mmu_t *mmu = NULL;
 
-    int pm_handle = -1;
+    void *pm_handle = NULL;
 
     /* used by debug verify code */
     unsigned long buf[PAGE_SIZE/sizeof(unsigned long)];
 
-    if ( mlock(&ctxt, sizeof(ctxt) ) ) {   
+    if ( mlock(&ctxt, sizeof(ctxt) ) )
+    {
         /* needed for when we do the build dom0 op, 
            but might as well do early */
         PERROR("Unable to mlock ctxt");
@@ -140,24 +145,28 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
 
     /* Start writing out the saved-domain record. */
     if ( xcio_read(ioctxt, signature, 16) ||
-         (memcmp(signature, "LinuxGuestRecord", 16) != 0) ) {
+         (memcmp(signature, "LinuxGuestRecord", 16) != 0) )
+    {
         xcio_error(ioctxt, "Unrecognised state format -- no signature found");
         goto out;
     }
 
     if ( xcio_read(ioctxt, name,                  sizeof(name)) ||
          xcio_read(ioctxt, &nr_pfns,              sizeof(unsigned long)) ||
-         xcio_read(ioctxt, pfn_to_mfn_frame_list, PAGE_SIZE) ) {
+         xcio_read(ioctxt, pfn_to_mfn_frame_list, PAGE_SIZE) )
+    {
         xcio_error(ioctxt, "Error reading header");
         goto out;
     }
 
-    if(read_vmconfig(ioctxt)){
+    if ( read_vmconfig(ioctxt) )
+    {
         xcio_error(ioctxt, "Error writing vmconfig");
         goto out;
     }
 
-    for ( i = 0; i < MAX_DOMAIN_NAME; i++ ) {
+    for ( i = 0; i < MAX_DOMAIN_NAME; i++ ) 
+    {
         if ( name[i] == '\0' ) break;
         if ( name[i] & 0x80 )
         {
@@ -167,7 +176,8 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
     }
     name[MAX_DOMAIN_NAME-1] = '\0';
 
-    if ( nr_pfns > 1024*1024 ) {
+    if ( nr_pfns > 1024*1024 )
+    {
         xcio_error(ioctxt, "Invalid state file -- pfn count out of range");
         goto out;
     }
@@ -177,19 +187,23 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
     pfn_type         = calloc(1, 4 * nr_pfns);    
     region_mfn       = calloc(1, 4 * MAX_BATCH_SIZE);    
 
-    if ( (pfn_to_mfn_table == NULL) || (pfn_type == NULL) || 
-         (region_mfn == NULL) ) {
+    if ( (pfn_to_mfn_table == NULL) ||
+         (pfn_type == NULL) || 
+         (region_mfn == NULL) ) 
+    {
         errno = ENOMEM;
         goto out;
     }
     
-    if ( mlock(region_mfn, 4 * MAX_BATCH_SIZE ) ) {
+    if ( mlock(region_mfn, 4 * MAX_BATCH_SIZE ) )
+    {
         xcio_error(ioctxt, "Could not mlock region_mfn");
         goto out;
     }
 
     /* Set the domain's name to that from the restore file */
-    if ( xc_domain_setname( xc_handle, dom, name ) ) {
+    if ( xc_domain_setname( xc_handle, dom, name ) )
+    {
         xcio_error(ioctxt, "Could not set domain name");
         goto out;
     }
@@ -208,24 +222,26 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = (domid_t)dom;
     op.u.getdomaininfo.ctxt = NULL;
-    if ( do_dom0_op(xc_handle, &op) < 0 ) {
+    if ( do_dom0_op(xc_handle, &op) < 0 )
+    {
         xcio_error(ioctxt, "Could not get information on new domain");
         goto out;
     }
     shared_info_frame = op.u.getdomaininfo.shared_info_frame;
 
-    if ( (pm_handle = init_pfn_mapper((domid_t)dom)) < 0 )
+    if ( (pm_handle = init_pfn_mapper((domid_t)dom)) == NULL )
         goto out;
 
-
-
     /* Build the pfn-to-mfn table. We choose MFN ordering returned by Xen. */
-    if ( get_pfn_list(xc_handle, dom, pfn_to_mfn_table, nr_pfns) != nr_pfns ) {
-        xcio_error(ioctxt, "Did not read correct number of frame numbers for new dom");
+    if ( get_pfn_list(xc_handle, dom, pfn_to_mfn_table, nr_pfns) != nr_pfns )
+    {
+        xcio_error(ioctxt, "Did not read correct number of frame "
+                   "numbers for new dom");
         goto out;
     }
 
-    if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL ) {
+    if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
+    {
         xcio_error(ioctxt, "Could not initialise for MMU updates");
         goto out;
     }
@@ -238,33 +254,39 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
      */
     prev_pc = 0;
 
-    n=0;
-    while(1) {
+    n = 0;
+    while ( 1 )
+    {
         int j;
         unsigned long region_pfn_type[MAX_BATCH_SIZE];
 
         this_pc = (n * 100) / nr_pfns;
-        if ( (this_pc - prev_pc) >= 5 ) {
+        if ( (this_pc - prev_pc) >= 5 )
+        {
             xcio_info(ioctxt, "\b\b\b\b%3d%%", this_pc);
             prev_pc = this_pc;
         }
 
-        if ( xcio_read(ioctxt, &j, sizeof(int)) ) {
+        if ( xcio_read(ioctxt, &j, sizeof(int)) )
+        {
             xcio_error(ioctxt, "Error when reading from state file");
             goto out;
         }
 
         DPRINTF("batch %d\n",j);
  
-        if ( j == -1 ) {
+        if ( j == -1 )
+        {
             verify = 1;
             printf("Entering page verify mode\n");
             continue;
         }
 
-        if ( j == 0 ) break;  /* our work here is done */
+        if ( j == 0 )
+            break;  /* our work here is done */
 
-        if( j > MAX_BATCH_SIZE ) {
+        if ( j > MAX_BATCH_SIZE )
+        {
             xcio_error(ioctxt, "Max batch size exceeded. Giving up.");
             goto out;
         }
@@ -274,10 +296,14 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
             goto out;
         }
 
-        for(i=0; i<j; i++) {
-            if ( (region_pfn_type[i] & LTAB_MASK) == XTAB) {
+        for ( i = 0; i < j; i++ )
+        {
+            if ( (region_pfn_type[i] & LTAB_MASK) == XTAB)
+            {
                 region_mfn[i] = 0; /* we know map will fail, but don't care */
-            } else {  
+            }
+            else
+            {  
                 pfn = region_pfn_type[i] & ~LTAB_MASK;
                 region_mfn[i] = pfn_to_mfn_table[pfn];
             }          
@@ -286,19 +312,22 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
         if ( (region_base = mfn_mapper_map_batch( xc_handle, dom, 
                                                   PROT_WRITE,
                                                   region_mfn,
-                                                  j )) == 0) {
+                                                  j )) == 0 )
+        {
             xcio_error(ioctxt, "map batch failed");
             goto out;
         }
 
-        for(i=0;i<j;i++) {
+        for ( i = 0; i < j; i++ )
+        {
             unsigned long *ppage;
 
             pfn = region_pfn_type[i] & ~LTAB_MASK;
 
             if ( (region_pfn_type[i] & LTAB_MASK) == XTAB) continue;
 
-            if (pfn>nr_pfns) {
+            if (pfn>nr_pfns)
+            {
                 xcio_error(ioctxt, "pfn out of range");
                 goto out;
             }
@@ -309,32 +338,36 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
 
             mfn = pfn_to_mfn_table[pfn];
 
-            if ( verify ) {
+            if ( verify )
                 ppage = (unsigned long*) buf;  /* debug case */
-            } else {
+            else
                 ppage = (unsigned long*) (region_base + i*PAGE_SIZE);
-            }
 
-            if ( xcio_read(ioctxt, ppage, PAGE_SIZE) ) {
+            if ( xcio_read(ioctxt, ppage, PAGE_SIZE) )
+            {
                 xcio_error(ioctxt, "Error when reading from state file");
                 goto out;
             }
 
-            switch( region_pfn_type[i] ) {
+            switch( region_pfn_type[i] )
+            {
             case 0:
                 break;
 
             case L1TAB:
             {
-                for ( k = 0; k < 1024; k++ ) {
-                    if ( ppage[k] & _PAGE_PRESENT ) {
+                for ( k = 0; k < 1024; k++ ) 
+                {
+                    if ( ppage[k] & _PAGE_PRESENT ) 
+                    {
                         xpfn = ppage[k] >> PAGE_SHIFT;
-
-                        if ( xpfn >= nr_pfns ) {
-                            xcio_error(ioctxt, "Frame number in type %lu page table is "
-                                  "out of range. i=%d k=%d pfn=0x%lx "
-                                  "nr_pfns=%lu", region_pfn_type[i]>>28, i, 
-                                  k, xpfn, nr_pfns);
+                        if ( xpfn >= nr_pfns )
+                        {
+                            xcio_error(ioctxt, "Frame number in type %lu page "
+                                       "table is out of range. i=%d k=%d "
+                                       "pfn=0x%lx nr_pfns=%lu", 
+                                       region_pfn_type[i]>>28, i, 
+                                       k, xpfn, nr_pfns);
                             goto out;
                         }
 
@@ -350,15 +383,19 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
             {
                 for ( k = 0; 
                       k < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); 
-                      k++ ) {
-                    if ( ppage[k] & _PAGE_PRESENT ) {
+                      k++ )
+                {
+                    if ( ppage[k] & _PAGE_PRESENT )
+                    {
                         xpfn = ppage[k] >> PAGE_SHIFT;
 
-                        if ( xpfn >= nr_pfns ) {
-                            xcio_error(ioctxt, "Frame number in type %lu page table is "
-                                  "out of range. i=%d k=%d pfn=%lu nr_pfns=%lu",
-                                  region_pfn_type[i]>>28, i, k, xpfn, nr_pfns);
-
+                        if ( xpfn >= nr_pfns )
+                        {
+                            xcio_error(ioctxt, "Frame number in type %lu page"
+                                       " table is out of range. i=%d k=%d "
+                                       "pfn=%lu nr_pfns=%lu",
+                                       region_pfn_type[i]>>28, i, k, 
+                                       xpfn, nr_pfns);
                             goto out;
                         }
 
@@ -371,21 +408,25 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
             break;
 
             default:
-                xcio_error(ioctxt, "Bogus page type %lx page table is out of range."
-                      " i=%d nr_pfns=%lu", region_pfn_type[i], i, nr_pfns);
+                xcio_error(ioctxt, "Bogus page type %lx page table is "
+                           "out of range. i=%d nr_pfns=%lu", 
+                           region_pfn_type[i], i, nr_pfns);
                 goto out;
 
             } /* end of page type switch statement */
 
-            if ( verify ) {
+            if ( verify )
+            {
                 int res = memcmp(buf, (region_base + i*PAGE_SIZE), PAGE_SIZE );
-                if (res) {
+                if ( res )
+                {
                     int v;
                     printf("************** pfn=%lx type=%lx gotcs=%08lx "
                            "actualcs=%08lx\n", pfn, pfn_type[pfn], 
                            csum_page(region_base + i*PAGE_SIZE), 
                            csum_page(buf));
-                    for ( v = 0; v < 4; v++ ) {
+                    for ( v = 0; v < 4; v++ )
+                    {
                         unsigned long *p = (unsigned long *)
                             (region_base + i*PAGE_SIZE);
                         if ( buf[v] != p[v] )
@@ -396,7 +437,8 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
             }
 
             if ( add_mmu_update(xc_handle, mmu,
-                                (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, pfn) ) {
+                                (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, pfn) )
+            {
                 printf("machpys mfn=%ld pfn=%ld\n",mfn,pfn);
                 goto out;
             }
@@ -407,16 +449,16 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
         n+=j; /* crude stats */
     }
 
-    printf("Received all pages\n");
-
     DPRINTF("Received all pages\n");
 
     /*
      * Pin page tables. Do this after writing to them as otherwise Xen
      * will barf when doing the type-checking.
      */
-    for ( i = 0; i < nr_pfns; i++ ) {
-        if ( pfn_type[i] == L1TAB ) {
+    for ( i = 0; i < nr_pfns; i++ )
+    {
+        if ( pfn_type[i] == L1TAB )
+        {
             if ( add_mmu_update(xc_handle, mmu,
                                 (pfn_to_mfn_table[i]<<PAGE_SHIFT) | 
                                 MMU_EXTENDED_COMMAND,
@@ -425,11 +467,14 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
                        (unsigned long)i, pfn_to_mfn_table[i]);
                 goto out;
             }
-        } else if ( pfn_type[i] == L2TAB ) {
+        }
+        else if ( pfn_type[i] == L2TAB )
+        {
             if ( add_mmu_update(xc_handle, mmu,
                                 (pfn_to_mfn_table[i]<<PAGE_SHIFT) | 
                                 MMU_EXTENDED_COMMAND,
-                                MMUEXT_PIN_L2_TABLE) ) {
+                                MMUEXT_PIN_L2_TABLE) )
+            {
                 printf("ERR pin L2 pfn=%lx mfn=%lx\n",
                        (unsigned long)i, pfn_to_mfn_table[i]);
                 goto out;
@@ -442,8 +487,9 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
     xcio_info(ioctxt, "\b\b\b\b100%%\nMemory reloaded.\n");
 
 
-    if ( xcio_read(ioctxt, &ctxt,                 sizeof(ctxt)) ||
-         xcio_read(ioctxt, shared_info,           PAGE_SIZE) ) {
+    if ( xcio_read(ioctxt, &ctxt,       sizeof(ctxt)) ||
+         xcio_read(ioctxt, shared_info, PAGE_SIZE) )
+    {
         xcio_error(ioctxt, "Error when reading from state file");
         goto out;
     }
@@ -463,13 +509,16 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
     unmap_pfn(pm_handle, p_srec);
 
     /* Uncanonicalise each GDT frame number. */
-    if ( ctxt.gdt_ents > 8192 ) {
+    if ( ctxt.gdt_ents > 8192 )
+    {
         xcio_error(ioctxt, "GDT entry count out of range");
         goto out;
     }
-    for ( i = 0; i < ctxt.gdt_ents; i += 512 ) {
+    for ( i = 0; i < ctxt.gdt_ents; i += 512 )
+    {
         pfn = ctxt.gdt_frames[i];
-        if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) ) {
+        if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
+        {
             xcio_error(ioctxt, "GDT frame number is bad");
             goto out;
         }
@@ -478,7 +527,8 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
 
     /* Uncanonicalise the page table base pointer. */
     pfn = ctxt.pt_base >> PAGE_SHIFT;
-    if ( (pfn >= nr_pfns) || (pfn_type[pfn] != L2TAB) ) {
+    if ( (pfn >= nr_pfns) || (pfn_type[pfn] != L2TAB) )
+    {
         printf("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx\n",
                pfn, nr_pfns, pfn_type[pfn], (unsigned long)L2TAB);
         xcio_error(ioctxt, "PT base is bad.");
@@ -499,11 +549,13 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
 
 
     /* Uncanonicalise the pfn-to-mfn table frame-number list. */
-    for ( i = 0; i < (nr_pfns+1023)/1024; i++ ) {
+    for ( i = 0; i < (nr_pfns+1023)/1024; i++ )
+    {
         unsigned long pfn, mfn;
 
         pfn = pfn_to_mfn_frame_list[i];
-        if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) ) {
+        if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NOTAB) )
+        {
             xcio_error(ioctxt, "PFN-to-MFN frame number is bad");
             goto out;
         }
@@ -515,15 +567,16 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
           mfn_mapper_map_batch(xc_handle, dom, 
                                PROT_WRITE,
                                pfn_to_mfn_frame_list,
-                               (nr_pfns+1023)/1024 )) == 0 ) {
+                               (nr_pfns+1023)/1024 )) == 0 )
+    {
         xcio_error(ioctxt, "Couldn't map pfn_to_mfn table");
         goto out;
     }
 
-    memcpy( live_pfn_to_mfn_table, pfn_to_mfn_table, 
-            nr_pfns*sizeof(unsigned long) );
+    memcpy(live_pfn_to_mfn_table, pfn_to_mfn_table, 
+           nr_pfns*sizeof(unsigned long) );
 
-    munmap( live_pfn_to_mfn_table, ((nr_pfns+1023)/1024)*PAGE_SIZE );
+    munmap(live_pfn_to_mfn_table, ((nr_pfns+1023)/1024)*PAGE_SIZE);
 
     /*
      * Safety checking of saved context:
@@ -538,20 +591,18 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
      *  9. debugregs are checked by Xen.
      *  10. callback code selectors need checking.
      */
-    for ( i = 0; i < 256; i++ ) {
+    for ( i = 0; i < 256; i++ )
+    {
         ctxt.trap_ctxt[i].vector = i;
         if ( (ctxt.trap_ctxt[i].cs & 3) == 0 )
             ctxt.trap_ctxt[i].cs = FLAT_GUESTOS_CS;
     }
-    if ( (ctxt.guestos_ss & 3) == 0 ){
+    if ( (ctxt.guestos_ss & 3) == 0 )
         ctxt.guestos_ss = FLAT_GUESTOS_DS;
-    }
-    if ( (ctxt.event_callback_cs & 3) == 0 ){
+    if ( (ctxt.event_callback_cs & 3) == 0 )
         ctxt.event_callback_cs = FLAT_GUESTOS_CS;
-    }
-    if ( (ctxt.failsafe_callback_cs & 3) == 0 ){
+    if ( (ctxt.failsafe_callback_cs & 3) == 0 )
         ctxt.failsafe_callback_cs = FLAT_GUESTOS_CS;
-    }
     if ( ((ctxt.ldt_base & (PAGE_SIZE - 1)) != 0) ||
          (ctxt.ldt_ents > 8192) ||
          (ctxt.ldt_base > HYPERVISOR_VIRT_START) ||
@@ -568,7 +619,8 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
 
     /* don't start the domain as we have console etc to set up */
   
-    if( rc == 0 ) {
+    if ( rc == 0 )
+    {
         /* Success: print the domain id. */
         xcio_info(ioctxt, "DOM=%lu\n", dom);
         return 0;
@@ -576,25 +628,20 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
 
 
  out:
-    if ( (rc != 0) && (dom != 0) ){
+    if ( (rc != 0) && (dom != 0) )
         xc_domain_destroy(xc_handle, dom);
-    }
-    if ( mmu != NULL ){
+    if ( mmu != NULL )
         free(mmu);
-    }
-    if ( pm_handle >= 0 ){
+    if ( pm_handle != NULL )
         (void)close_pfn_mapper(pm_handle);
-    }
-    if ( pfn_to_mfn_table != NULL ){
+    if ( pfn_to_mfn_table != NULL )
         free(pfn_to_mfn_table);
-    }
-    if ( pfn_type != NULL ){
+    if ( pfn_type != NULL )
         free(pfn_type);
-    }
 
-    if ( rc == 0 ){
+    if ( rc == 0 )
         ioctxt->domain = dom;
-    }
+
     DPRINTF("Restore exit with rc=%d\n",rc);
     return rc;
 }
index 04a47b5068b44df57e957374cbf7ea9dad0078ad..833a533ab6c47363e575d474e278d55c66c42e6a 100644 (file)
@@ -13,7 +13,7 @@
 #define DPRINTF(x)
 #endif
 
-static int loadelfimage(gzFile, int, unsigned long *, unsigned long,
+static int loadelfimage(gzFile, void *, unsigned long *, unsigned long,
                         unsigned long *, unsigned long *,
                         unsigned long *, unsigned long *);
 
@@ -77,9 +77,10 @@ static int setup_guestos(int xc_handle,
     shared_info_t *shared_info;
     unsigned long ksize;
     mmu_t *mmu = NULL;
-    int pm_handle, i;
+    void  *pm_handle = NULL;
+    int i;
 
-    if ( (pm_handle = init_pfn_mapper((domid_t)dom)) < 0 )
+    if ( (pm_handle = init_pfn_mapper((domid_t)dom)) == NULL )
         goto error_out;
 
     if ( (page_array = malloc(tot_pages * sizeof(unsigned long))) == NULL )
@@ -201,7 +202,7 @@ static int setup_guestos(int xc_handle,
  error_out:
     if ( mmu != NULL )
         free(mmu);
-    if ( pm_handle >= 0 )
+    if ( pm_handle != NULL )
         (void)close_pfn_mapper(pm_handle);
     if ( page_array == NULL )
         free(page_array);
@@ -412,7 +413,7 @@ myseek(gzFile gfd, off_t offset, int whence)
 #define IS_BSS(p) (p.p_filesz < p.p_memsz)
 
 static int
-loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array,
+loadelfimage(gzFile kernel_gfd, void *pm_handle, unsigned long *page_array,
              unsigned long tot_pages, unsigned long *virt_load_addr,
              unsigned long *ksize, unsigned long *symtab_addr,
              unsigned long *symtab_len)
index 344f48254daa74db63c041e705f9bdceabd0f274..8807f8a9bf05f0feb1d5b1f394894dcf2562b3f4 100644 (file)
 
 #include "xc_private.h"
 
-int init_pfn_mapper(domid_t domid)
+#define MAX_EXTENTS 8
+typedef struct {
+    int fd;
+    struct {
+        void         *base; 
+        unsigned long length;
+    } extent[MAX_EXTENTS];
+} mapper_desc_t;
+
+void *init_pfn_mapper(domid_t domid)
 {
-    int fd = open("/dev/mem", O_RDWR);
-    if ( fd >= 0 )
-        (void)ioctl(fd, _IO('M', 1), (unsigned long)domid);
-    return fd;
+    int            fd = open("/dev/mem", O_RDWR);
+    mapper_desc_t *desc;
+
+    if ( fd < 0 )
+        return NULL;
+
+    if ( (desc = malloc(sizeof(*desc))) == NULL )
+    {
+        close(fd);
+        return NULL;
+    }
+
+    (void)ioctl(fd, _IO('M', 1), (unsigned long)domid);
+
+    memset(desc, 0, sizeof(*desc));
+    desc->fd = fd;
+
+    return desc;
 }
 
-int close_pfn_mapper(int pm_handle)
+int close_pfn_mapper(void *pm_handle)
 {
-    return close(pm_handle);
+    mapper_desc_t *desc = pm_handle;
+    int            i;
+
+    for ( i = 0; i < MAX_EXTENTS; i++ )
+    {
+        if ( desc->extent[i].base != NULL )
+            (void)munmap(desc->extent[i].base, desc->extent[i].length);
+    }
+
+    close(desc->fd);
+    free(desc);
+
+    return 0;
 }
 
-void *map_pfn_writeable(int pm_handle, unsigned long pfn)
+static int get_free_offset(mapper_desc_t *desc)
 {
-    void *vaddr = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
-                       MAP_SHARED, pm_handle, pfn << PAGE_SHIFT);
+    int i;
+
+    for ( i = 0; i < MAX_EXTENTS; i++ )
+    {
+        if ( desc->extent[i].base == NULL )
+            break;
+    }
+
+    if ( i == MAX_EXTENTS )
+    {
+        fprintf(stderr, "Extent overflow in map_pfn_*()!\n");
+        fflush(stderr);
+        *(int*)0=0; /* XXX */
+    }
+
+    return i;
+}
+
+void *map_pfn_writeable(void *pm_handle, unsigned long pfn)
+{
+    mapper_desc_t *desc = pm_handle;
+    void          *vaddr;
+    int            off;
+
+    vaddr = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
+                 MAP_SHARED, desc->fd, pfn << PAGE_SHIFT);
     if ( vaddr == MAP_FAILED )
         return NULL;
+
+    off = get_free_offset(desc);
+    desc->extent[off].base   = vaddr;
+    desc->extent[off].length = PAGE_SIZE;
+
     return vaddr;
 }
 
-void *map_pfn_readonly(int pm_handle, unsigned long pfn)
+void *map_pfn_readonly(void *pm_handle, unsigned long pfn)
 {
-    void *vaddr = mmap(NULL, PAGE_SIZE, PROT_READ,
-                       MAP_SHARED, pm_handle, pfn << PAGE_SHIFT);
+    mapper_desc_t *desc = pm_handle;
+    void          *vaddr;
+    int            off;
+
+    vaddr = mmap(NULL, PAGE_SIZE, PROT_READ,
+                 MAP_SHARED, desc->fd, pfn << PAGE_SHIFT);
     if ( vaddr == MAP_FAILED )
         return NULL;
+
+    off = get_free_offset(desc);
+    desc->extent[off].base   = vaddr;
+    desc->extent[off].length = PAGE_SIZE;
+
     return vaddr;
 }
 
-void unmap_pfn(int pm_handle, void *vaddr)
+void unmap_pfn(void *pm_handle, void *vaddr)
 {
-    (void)munmap(vaddr, PAGE_SIZE);
+    mapper_desc_t *desc = pm_handle;
+    int            i;
+    unsigned long  len = 0;
+
+    for ( i = 0; i < MAX_EXTENTS; i++ )
+    {
+        if ( desc->extent[i].base == vaddr )
+        {
+            desc->extent[i].base = NULL;
+            len = desc->extent[i].length;
+        }
+    }
+
+    if ( len == 0 )
+        *(int*)0 = 0; /* XXX */
+
+    (void)munmap(vaddr, len);
 }
 
 /*******************/
 
-void * mfn_mapper_map_batch(int xc_handle, domid_t dom, int prot,
-                            unsigned long *arr, int num )
+void *mfn_mapper_map_batch(int xc_handle, domid_t dom, int prot,
+                           unsigned long *arr, int num )
 {
     privcmd_mmapbatch_t ioctlx; 
     void *addr;
-    addr = mmap( NULL, num*PAGE_SIZE, prot, MAP_SHARED, xc_handle, 0 );
-    if (addr)
+    addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_SHARED, xc_handle, 0);
+    if ( addr != NULL )
     {
         ioctlx.num=num;
         ioctlx.dom=dom;
@@ -69,15 +158,15 @@ void * mfn_mapper_map_batch(int xc_handle, domid_t dom, int prot,
 
 /*******************/
 
-void * mfn_mapper_map_single(int xc_handle, domid_t dom,
-                             int size, int prot,
-                             unsigned long mfn )
+void *mfn_mapper_map_single(int xc_handle, domid_t dom,
+                            int size, int prot,
+                            unsigned long mfn )
 {
     privcmd_mmap_t ioctlx; 
     privcmd_mmap_entry_t entry; 
     void *addr;
-    addr = mmap( NULL, size, prot, MAP_SHARED, xc_handle, 0 );
-    if (addr)
+    addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
+    if ( addr != NULL )
     {
         ioctlx.num=1;
         ioctlx.dom=dom;
@@ -85,7 +174,7 @@ void * mfn_mapper_map_single(int xc_handle, domid_t dom,
         entry.va=(unsigned long) addr;
         entry.mfn=mfn;
         entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT;
-        if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx ) <0 )
+        if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx ) < 0 )
         {
             munmap(addr, size);
             return 0;
index 742185161b3c09840d200f0368c5dfb85d3cfcc1..aff7a80463abec2a49b3605e034ea765a65f26de 100644 (file)
@@ -131,11 +131,11 @@ static inline int do_multicall_op(int xc_handle,
 /*
  * PFN mapping.
  */
-int init_pfn_mapper(domid_t domid);
-int close_pfn_mapper(int pm_handle);
-void *map_pfn_writeable(int pm_handle, unsigned long pfn);
-void *map_pfn_readonly(int pm_handle, unsigned long pfn);
-void unmap_pfn(int pm_handle, void *vaddr);
+void *init_pfn_mapper(domid_t domid);
+int close_pfn_mapper(void *pm_handle);
+void *map_pfn_writeable(void *pm_handle, unsigned long pfn);
+void *map_pfn_readonly(void *pm_handle, unsigned long pfn);
+void unmap_pfn(void *pm_handle, void *vaddr);
 int get_pfn_type_batch(int xc_handle, u32 dom, int num, unsigned long *arr);
 unsigned long csum_page (void * page);